home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pine / adrbklib.h < prev    next >
C/C++ Source or Header  |  1996-04-18  |  26KB  |  536 lines

  1. /*----------------------------------------------------------------------
  2.   $Id: adrbklib.h,v 4.58 1996/04/18 22:32:26 hubert Exp $
  3.  
  4.             T H E    P I N E    M A I L   S Y S T E M
  5.  
  6.    Laurence Lundblade and Mike Seibel
  7.    Networks and Distributed Computing
  8.    Computing and Communications
  9.    University of Washington
  10.    Administration Builiding, AG-44
  11.    Seattle, Washington, 98195, USA
  12.    Internet: lgl@CAC.Washington.EDU
  13.              mikes@CAC.Washington.EDU
  14.  
  15.    Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  16.  
  17.  
  18.    Pine and Pico are registered trademarks of the University of Washington.
  19.    No commercial use of these trademarks may be made without prior written
  20.    permission of the University of Washington.
  21.  
  22.    Pine, Pico, and Pilot software and its included text are Copyright
  23.    1989-1996 by the University of Washington.
  24.  
  25.    The full text of our legal notices is contained in the file called
  26.    CPYRIGHT, included with this distribution.
  27.  
  28.  
  29.    Pine is in part based on The Elm Mail System:
  30.     ***********************************************************************
  31.     *  The Elm Mail System  -  Revision: 2.13                             *
  32.     *                                                                     *
  33.     *             Copyright (c) 1986, 1987 Dave Taylor              *
  34.     *             Copyright (c) 1988, 1989 USENET Community Trust   *
  35.     ***********************************************************************
  36.  
  37.  
  38.   ----------------------------------------------------------------------*/
  39.  
  40. #ifndef _ADRBKLIB_INCLUDED
  41. #define _ADRBKLIB_INCLUDED
  42.  
  43. /*
  44.  *  Some notes:
  45.  *
  46.  * There is considerable indirection going on to get to an address book
  47.  * entry.  The idea is that we don't want to have to read in the entire
  48.  * address book (takes too long and uses too much memory) so we have a
  49.  * quick way to get to any entry.  There are "count" entries in the addrbook.
  50.  * For each entry, there is an EntryRef element.  So there is an
  51.  * array of count EntryRef elements, 0, ..., count-1.  These EntryRef elements
  52.  * aren't all kept in memory.  Instead, there is a cache of EntryRef
  53.  * elements.  The size of that cache is set with adrbk_set_nominal_cachesize().
  54.  * That cache is fronted by a hashtable with the hashvalue just the element
  55.  * number mod size_of_hashtable.  The size of the hashtable is just set so
  56.  * that every hash bucket has 10 entries in it, so we have a constant short
  57.  * time for looking for a cache hit.  EntryRef entries are prebuilt from
  58.  * the addrbook file and stored in the EntryRef section of the addrbook.lu
  59.  * file.  An EntryRef element consists of:
  60.  *      uid_nick, uid_addr  Unique id's computed from nickname and address
  61.  *      offset              Offset into addrbook to start of nickname
  62.  *      next_nick           Next entry for nickname with same hash value
  63.  *      next_addr           Next entry for address with same hash value
  64.  *      ae                  Pointer to cached AdrBk_Entry (not stored on disk)
  65.  * To get an AdrBk_Entry, say for element 13, adrbk_get_entryref(13) is
  66.  * called.  That looks in the appropriate hash bucket for 13 and runs
  67.  * through the list looking for a match on element 13.  If it doesn't find
  68.  * it, it reads the entry from the addrbook.lu file as above.  That entry
  69.  * can be found easily because it is at a calculable offset from the
  70.  * start of the addrbook.lu file.  Then adrbk_init_ae() is called to parse
  71.  * the entry and fill in an ae, which is pointed to by the cached EntryRef.
  72.  * That's how you look up a particular entry *number* in the addrbook.  That
  73.  * would be used for browsing the addrbook or searching the addrbook.
  74.  *
  75.  * The order that the address book is stored in on disk is the order that
  76.  * the entries will be displayed in.  When an address book is opened,
  77.  * if it is ReadWrite the sort order is checked and it is sorted if it is
  78.  * out of order.  If an addrbook is already correctly sorted but doesn't
  79.  * have a .lu file yet, the .lu file will be created, then the sort will be
  80.  * checked by going through all N entries.  The sort_rule will be stored
  81.  * into the .lu file so that the next time this happens the check can
  82.  * be avoided.  That is, once the addrbook is sorted once, all operations
  83.  * on it preserve the sort order.  So unless it is changed externally, or
  84.  * the .lu file is removed, or the sort_rule is changed, this check will
  85.  * never have to look at any of the entries again.
  86.  *
  87.  * You also want to be able to lookup an entry based on the nickname.  The
  88.  * composer does this all the time by calling build_address().  That needs
  89.  * to be very fast, so is done through another hashtable.  This table is
  90.  * also precomputed and stored in the addrbook.lu file.  When the addrbook
  91.  * is first opened, that hash table is read into memory.  Each entry in the
  92.  * hashtable is a adrbk_cntr_t element number, which points to the head
  93.  * of the list of entries with the same hash value.  That list is what
  94.  * uses the next_nick variable in the EntryRef.  The hashtable is not very
  95.  * large.  Just four (or 2) bytes per entry and size of hashtable entries.  The
  96.  * size of the table varies with the size of the addrbook, and is set by
  97.  * the function hashtable_size().  It is also stored in the addrbook.lu
  98.  * file so need not be the value returned by hashtable_size.  That hashtable
  99.  * is kept open the whole time Pine is running, once it has been opened.  To
  100.  * look up an entry for nickname "nick", you compute the hash value (ab_hash)
  101.  * of "nick" and the uid (ab_uid) of "nick".  Look in the hash array at
  102.  * element number hash_value and find a pointer (an index into the EntryRef
  103.  * array).  Now you would get that EntryRef just like above, since you
  104.  * are now working with the element number.  Check to see if that EntryRef
  105.  * has the same uid as "nick".  If so, that's the one you want.  If not,
  106.  * next_nick is the index of the next entry with the same hash value.
  107.  * Follow that list checking uid's until you find it or hit the end.
  108.  * There is an entirely analogous hash table for lookup by address instead
  109.  * of lookup by nickname.  That only applies to addresses of Single entries,
  110.  * not Lists.
  111.  *
  112.  * Some sizes:
  113.  *
  114.  *  AdrHash is an array of adrbk_cntr_t of length hashtable_size.
  115.  *  This size is usually set by the hashtable_size function.
  116.  *  There are two of those, one for nicknames and one for addresses.
  117.  *  These are kept open the whole time the program is being run (once opened).
  118.  *  Those are also stored on disk in addrbook.lu.  They take up more
  119.  *  space there since they are written out in ASCII for portability.
  120.  *
  121.  *  An EntryRef cache element is size 16-20.  The size of this cache is usually
  122.  *  kept fairly small (200) but sorting cries out for it to be larger.
  123.  *  When sorting in Unix, it is set equal to the "count" of the addrbook,
  124.  *  smaller for DOS.  Each valid EntryRef cache element points to an
  125.  *  EntryRef in memory.  Each of those is 20-24 fixed bytes.  Part of that is
  126.  *  a pointer to a possible cached AdrBk_Entry.  An AdrBk_Entry is 22 bytes
  127.  *  of fixed space, but it also has pointers to variable amounts of memory
  128.  *  for nickname, fullname, addresses, fcc, and comments.  A typical
  129.  *  entry probably uses about 50 bytes of that extra space, so altogether,
  130.  *  a cached EntryRef with a fully-filled in ae takes around 100 bytes.
  131.  *  If you had a 30,000 entry addrbook, setting the cache size to "count"
  132.  *  for sorting takes up about 3,000,000 bytes of memory.
  133.  *
  134.  * That's the story for adrbklib.c.  There is also some allocation happening
  135.  * in addrbook.c.  In particular, the display is a window into an array
  136.  * of rows, at least one row per addrbook entry plus more for lists.
  137.  * Each row is an AddrScrn_Disp structure and those should typically take
  138.  * up 6 or 8 bytes.  A cached copy of addrbook entries is not kept, just
  139.  * the element number to look it up (and often get it out of the EntryRef
  140.  * cache).  In order to avoid having to allocate all those rows, this is
  141.  * also in the form of a cache.  Only 3 * screen_length rows are kept in
  142.  * the cache, and the cache is always a simple interval of rows.  That is,
  143.  * rows between valid_low and valid_high are all in the cache.  Row numbers
  144.  * in the display list are a little mysterious.  There is no origin.  That
  145.  * is, you don't necessarily know where the start or end of the display
  146.  * is.  You only know how to go forward and backward and how to "warp"
  147.  * to new locations in the display and go forward and backward from there.
  148.  * This is because we don't know how many rows there are all together.  It
  149.  * is also a way to avoid searching through everything to get somewhere.
  150.  * If you want to go to the End, you warp there and start backwards instead
  151.  * of reading through all the entries to get there.  If you edit an entry
  152.  * so that it sorts into a new location, you warp to that new location to
  153.  * save processing all of the entries in between.
  154.  *
  155.  *
  156.  * Notes about RFC1522 encoding:
  157.  *
  158.  * If the fullname field contains other than US-ASCII characters, it is
  159.  * encoded using the rules of RFC1522 or its successor.  The value actually
  160.  * stored in the file is encoded, even if it matches the character set of
  161.  * the user.  This is so it is easy to pass the entry around or to change
  162.  * character sets without invalidating entries in the address book.  When
  163.  * a fullname is displayed, it is first decoded.  If the fullname field is
  164.  * encoded as being from a character set other than the user's character
  165.  * set, that will be retained until the user edits the field.  Then it will
  166.  * change over to the user's character set.  The comment field works in
  167.  * the same way, as do the "phrase" fields of any addresses.  On outgoing
  168.  * mail, the correct character set will be retained if you use ComposeTo
  169.  * from the address book screen.  However, if you use a nickname from the
  170.  * composer or ^T from the composer, the character set will be lost if it
  171.  * is different from the user's character set.
  172.  */
  173.  
  174. #define NFIELDS 11 /* one more than num of data fields in addrbook entry */
  175.  
  176. /*
  177.  * Disk file takes up more space when HUGE is defined, but we think it is
  178.  * not enough more to offset the convenience of no limits.  So it is always
  179.  * defined.  Should still work if you want to undefine it.
  180.  */
  181. #define HUGE_ADDRBOOKS
  182.  
  183. /*
  184.  * The type a_c_arg_t is a little confusing.  It's the type we use in
  185.  * place of adrbk_cntr_t when we want to pass an adrbk_cntr_t in an argument.
  186.  * We were running into problems with the integral promotion of adrbk_cntr_t
  187.  * args.  A_c_arg_t has to be large enough to hold a promoted adrbk_cntr_t.
  188.  * So, if adrbk_cntr_t is unsigned short, then a_c_arg_t needs to be int if
  189.  * int is larger than short, or unsigned int if short is same size as int.
  190.  * Since usign16_t always fits in a short, a_c_arg_t of unsigned int should
  191.  * always work for !HUGE.  For HUGE, usign32_t will be either an unsigned int
  192.  * or an unsigned long.  If it is an unsigned long, then a_c_arg_t better be
  193.  * an unsigned long, too.  If it is an unsigned int, then a_c_arg_t could
  194.  * be an unsigned int, too.  However, if we just make it unsigned long, then
  195.  * it will be the same in all cases and big enough in all cases.
  196.  *
  197.  * In the HUGE case, we could use usign32_t for the a_c_arg_t typedef.
  198.  * There is no actual advantage to be gained, though.  The only place it
  199.  * would make a difference is on machines where an int is 32 bits and a
  200.  * long is 64 bits, in which case the 64-bit long is probably the more
  201.  * efficient size to use anyway.
  202.  */
  203.  
  204. #ifdef HUGE_ADDRBOOKS
  205.  
  206. typedef usign32_t adrbk_cntr_t;  /* addrbook counter type                */
  207. typedef unsigned long a_c_arg_t;     /* type of arg passed for adrbk_cntr_t  */
  208. #define NO_NEXT ((adrbk_cntr_t)-1)
  209. #define MAX_ADRBK_SIZE (2000000000L) /* leave room for extra display lines   */
  210. #define MAX_HASHTABLE_SIZE 150000
  211.  
  212. # else /* !HUGE_ADDRBOOKS */
  213.  
  214. typedef usign16_t adrbk_cntr_t; /* addrbook counter type                */
  215. typedef unsigned a_c_arg_t;          /* type of arg passed for addrbk_cntr_t */
  216. #define NO_NEXT ((adrbk_cntr_t)-1)
  217. #define MAX_ADRBK_SIZE ((long)(NO_NEXT - 2))
  218. #define MAX_HASHTABLE_SIZE 60000
  219.  
  220. # endif /* !HUGE_ADDRBOOKS */
  221.  
  222. /*
  223.  * The value NO_NEXT is reserved to mean that there is no next address, or that
  224.  * there is no address number to return.  This is similar to getc returning
  225.  * -1 when there is no char to get, but since we've defined this to be
  226.  * unsigned we need to reserve one of the valid values for this purpose.
  227.  * With current implementation it needs to be all 1's, so memset initialization
  228.  * will work correctly.
  229.  */
  230.  
  231. typedef long adrbk_uid_t;   /* the UID of a name or address */
  232.  
  233. typedef enum {ReadOnly, ReadWrite, NoAccess, NoExists} AccessType;
  234. typedef enum {NotSet, Single, List} Tag;
  235. typedef enum {Normal, Delete, SaveDelete, Lock, Unlock} Handling;
  236.  
  237. /* This is what is actually used by the routines that manipulate things */
  238. typedef struct adrbk_entry {
  239.     char *nickname;
  240.     char *fullname;    /* of simple addr or list                        */
  241.     union addr {
  242.         char *addr;    /* for simple Single entries                     */
  243.         char **list;   /* for distribution lists                        */
  244.     } addr;
  245.     char *fcc;         /* fcc specific for when sending to this address */
  246.     char *extra;       /* comments field                                */
  247.     char  referenced;  /* for detecting loops during lookup             */
  248.     Tag   tag;         /* single addr (Single) or a list (List)         */
  249. } AdrBk_Entry;
  250.  
  251. /*
  252.  * This points to the data in a file.  It gives us a smaller way to store
  253.  * data and a fast way to lookup a particular entry.  When we need the
  254.  * actual data we look in the file and produce an AdrBk_Entry.
  255.  */
  256. typedef struct entry_ref {
  257.     adrbk_uid_t  uid_nick;  /* uid(nickname) */
  258.     adrbk_uid_t  uid_addr;  /* uid(address) */
  259.     long         offset;    /* offset into file where this entry starts    */
  260.     adrbk_cntr_t next_nick; /* index of next nickname with same hash value */
  261.     adrbk_cntr_t next_addr;
  262.     AdrBk_Entry *ae;        /* cached ae */
  263. } EntryRef;
  264.  
  265. typedef struct er_cache_elem {
  266.     EntryRef *entry;            /* the cached entryref */
  267.     struct er_cache_elem *next; /* pointers to other cached entryrefs */
  268.     struct er_cache_elem *prev;
  269.     adrbk_cntr_t elem;          /* the index in the entryref array of entry */
  270.     Handling handling;          /* handling instructions */
  271.     unsigned char lock_ref_count; /* when reaches zero, it's unlocked */
  272. }ER_CACHE_ELEM_S;
  273.  
  274. /*
  275.  * hash(nickname) -> index into harray
  276.  * harray(index) is an index into an array of EntryRef's.
  277.  */
  278. typedef struct adrhash {
  279.     adrbk_cntr_t *harray;   /* the hash array, alloc'd (hash(name) points
  280.                    into this array and the value in this
  281.                    array is an index into the EntryRef array */
  282. } AdrHash;
  283.  
  284. /* information useful for displaying the addrbook */
  285. typedef struct width_stuff {
  286.     int max_nickname_width;
  287.     int max_fullname_width;
  288.     int max_addrfield_width;
  289.     int max_fccfield_width;
  290.     int third_biggest_fullname_width;
  291.     int third_biggest_addrfield_width;
  292.     int third_biggest_fccfield_width;
  293. } WIDTH_INFO_S;
  294.  
  295. typedef struct expanded_list {
  296.     adrbk_cntr_t          ent;
  297.     struct expanded_list *next;
  298. } EXPANDED_S;
  299.  
  300. typedef struct adrbk {
  301.     char         *orig_filename;       /* passed in filename                 */
  302.     char         *filename;            /* addrbook filename                  */
  303.     char         *temp_filename;       /* tmp file while writing out changes */
  304.     FILE         *fp;                  /* fp for filename                    */
  305.     AdrHash      *hash_by_nick;
  306.     AdrHash      *hash_by_addr;
  307.     char         *hashfile;
  308.     int           delete_hashfile;     /* remove tmp hashfile when done      */
  309.     char         *temp_hashfile;       /* tmp file while writing out changes */
  310.     FILE         *fp_hash;
  311.     AccessType    hashfile_access;     /* access permission for hashfile     */
  312.     adrbk_cntr_t  htable_size;         /* how many entries in AdrHash tables */
  313.     adrbk_cntr_t  count;               /* how many entries in addrbook       */
  314.     time_t        last_change_we_know_about;/* to look for others changing it*/
  315.     ER_CACHE_ELEM_S **head_cache_elem; /* array of cache elem heads          */
  316.     ER_CACHE_ELEM_S **tail_cache_elem;
  317.     int            *n_ae_cached_in_this_bucket;
  318.     long            nominal_max_cached;
  319.     adrbk_cntr_t    er_hashsize;
  320.     WIDTH_INFO_S  widths;              /* helps addrbook.c format columns    */
  321.     long          deleted_cnt;         /* how many #DELETED entries in abook */
  322.     int           sort_rule;
  323.     EXPANDED_S   *exp;                 /* this is for addrbook.c to use.  A
  324.                    list of expanded list entry nums is kept here */
  325.     EXPANDED_S   *checks;              /* this is for addrbook.c to use.  A
  326.                    list of checked entry nums is kept here */
  327. } AdrBk;
  328.  
  329. #define ONE_HUNDRED_DAYS (60L * 60L * 24L * 100L)
  330. /*
  331.  * When address book entries are deleted, they are left in the file
  332.  * with the nickname prepended with a string like #DELETED-96/01/25#, 
  333.  * which stands for year 96, month 1, day 25 of the month.  When one of
  334.  * these entries is more than ABOOK_DELETED_EXPIRE_TIME seconds old,
  335.  * then it will be totally removed from the address book the next time
  336.  * and adrbk_write() is done.  This is for emergencies where somebody
  337.  * deletes something from their address book and would like to get it
  338.  * back.  You get it back by editing the nickname field manually to remove
  339.  * the extra 18 characters off the front.
  340.  */
  341. #define ABOOK_DELETED_EXPIRE_TIME   ONE_HUNDRED_DAYS
  342.  
  343.  
  344. /*
  345.  * There are no restrictions on the length of any of the fields, except that
  346.  * there are some restrictions in the current input routines.
  347.  * There can be no more than 65534 entries (unless HUGE) in a single addrbook.
  348.  */
  349.  
  350. /*
  351.  * The on-disk address book has entries that look like:
  352.  *
  353.  * Nickname TAB Fullname TAB Address_Field TAB Fcc TAB Comment
  354.  *
  355.  * An entry may be broken over more than one line but only at certain
  356.  * spots.  A continuation line starts with spaces (spaces, not white space).
  357.  * One place a line break can occur is after any of the TABs.  The other
  358.  * place is in the middle of a list of addresses, between addresses.
  359.  * The Address_Field may be either a simple address without the fullname
  360.  * or brackets, or it may be an address list.  An address list is
  361.  * distinguished by the fact that it begins with "(" and ends with ")".
  362.  * Addresses within a list are comma separated and each address in the list
  363.  * may be a full rfc822 address, including Fullname and so on.
  364.  *
  365.  * Examples:
  366.  * fred TAB Flintstone, Fred TAB fred@bedrock.net TAB fcc-flintstone TAB comment
  367.  * or
  368.  * fred TAB Flintstone, Fred TAB \n
  369.  *    fred@bedrock.net TAB fcc-flintstone TAB \n
  370.  *    comment
  371.  * somelist TAB Some List TAB (fred, \n
  372.  *    Barney Rubble <barney@bedrock.net>, wilma@bedrock.net) TAB \n
  373.  *    fcc-for-some-list TAB comment
  374.  *
  375.  * There is also an on-disk file (called hashfile in the structure)
  376.  * which is useful for quick access to particular entries.  It has the
  377.  * form:
  378.  *                Header
  379.  *                EntryRef Array
  380.  *                HashTable by Nickname
  381.  *                HashTable by Address
  382.  *                Trailer
  383.  *
  384.  * This file is written in ASCII so that it will be portable to multiple
  385.  * clients.  It is named addrbook.lu, where addrbook is the name of the
  386.  * addrbook file.  lu stands for LookUp.
  387.  *
  388.  *       Header -- magic number "P # * E @"
  389.  *            <SPACE> two character version string
  390.  *            <SPACE> hash table size "\n" integer padded on left with spaces
  391.  * ifdef HUGE_ADDRBOOKS
  392.  *    It takes up 10 character slots
  393.  * else
  394.  *    Value restricted to take up 5 character slots
  395.  *
  396.  * EntryRef Arr -- An array of N OnDiskEntryRef's, where N is the number
  397.  *                     of entries in the address book.  Each entry is followed
  398.  *                     by "\n".
  399.  *
  400.  *    HashTables -- Arrays of hash table size integers, each of which is
  401.  *                     padded on left with spaces so it takes up 5 character
  402.  *                     (10 if HUGE_ADDRBOOKS)
  403.  *                     slots.  Each integer ends with a "\n" to make it
  404.  *                     easier to use debugging tools.
  405.  *    and another one of those for by address hash table
  406.  *
  407.  *      Trailer -- magic number "P # * E @"
  408.  *            <SPACE> N  "\n" the same N as the number of EntryRef entries
  409.  *        (N is 10 wide if HUGE_ADDRBOOKS, 5 otherwise)
  410.  *           DELETED_CNT "\n"  (11 chars wide, count of #DELETED lines)
  411.  *           W1 W2 W3 W4 W5 W6 W7 "\n"   These W's are widths for helping
  412.  *                             to make a nice display of the addrbook.  Each
  413.  *                             consists of a SPACE followed by a one or two
  414.  *                             digit number.
  415.  *           time created        10 bytes, seconds since Jan 1 70
  416.  *           <SPACE> sort_rule "\n"  Sort rule used to sort last time
  417.  *                                    (from AB_SORT... in pine.h)
  418.  *                                    2 bytes, decimal number.
  419.  *                    W1 = max_nickname_width
  420.  *                    W2 = max_fullname_width
  421.  *                    W3 = max_addrfield_width
  422.  *                    W4 = max_fccfield_width
  423.  *                    W5 = third_biggest_fullname_width
  424.  *                    W6 = third_biggest_addrfield_width
  425.  *                    W7 = third_biggest_fccfield_width
  426.  *
  427.  * Each OnDiskEntryRef looks like:
  428.  *      next_nick  -- 5 bytes, positive integer padded on left with spaces.
  429.  *      next_addr  -- 5 bytes, positive integer padded on left with spaces.
  430.  *                   (each of those is 10 with HUGE_ADDRBOOKS)
  431.  *      uid_nick   -- 11 bytes, integer padded on left with spaces.
  432.  *      uid_addr   -- 11 bytes, integer padded on left with spaces.
  433.  *      offset     -- 10 bytes, positive integer padded on left with spaces.
  434.  * Each of these is separated by an extra SPACE, as well, so there are
  435.  * 47 bytes per array element (counting the newline).
  436.  */
  437.  
  438. #define ADRHASH_FILE_SUFFIX      ".lu"
  439. #ifdef HUGE_ADDRBOOKS
  440. #define ADRHASH_FILE_VERSION_NUM "14"
  441. #else
  442. #define ADRHASH_FILE_VERSION_NUM "13"
  443. #endif
  444. #define PMAGIC                   "P#*E@"
  445. #define LEGACY_PMAGIC            "P#*@ "  /* sorry about that */
  446.  
  447. #define SIZEOF_PMAGIC       (5)
  448. #define SIZEOF_SPACE        (1)
  449. #define SIZEOF_NEWLINE      (1)
  450. #define SIZEOF_VERSION_NUM  (2)
  451. #define SIZEOF_SORT_RULE    (2)
  452. #define SIZEOF_WIDTH        (2)
  453. #define SIZEOF_ASCII_USHORT (5)
  454. #define SIZEOF_ASCII_ULONG  (10)
  455. #define SIZEOF_ASCII_LONG   (11)  /* because of possible "-" sign */
  456. #define SIZEOF_UID          SIZEOF_ASCII_LONG
  457. #define SIZEOF_FILEOFFSET   SIZEOF_ASCII_ULONG
  458. #define SIZEOF_TIMESTAMP    SIZEOF_ASCII_ULONG
  459. #define SIZEOF_DELETED_CNT  SIZEOF_ASCII_LONG
  460.  
  461. #ifdef HUGE_ADDRBOOKS
  462.  
  463. #define SIZEOF_HASH_SIZE    SIZEOF_ASCII_ULONG
  464. #define SIZEOF_HASH_INDEX   SIZEOF_ASCII_ULONG
  465.  
  466. #else /* !HUGE_ADDRBOOKS */
  467.  
  468. #define SIZEOF_HASH_SIZE    SIZEOF_ASCII_USHORT
  469. #define SIZEOF_HASH_INDEX   SIZEOF_ASCII_USHORT
  470.  
  471. #endif /* !HUGE_ADDRBOOKS */
  472.  
  473. #define SIZEOF_COUNT        SIZEOF_HASH_INDEX
  474.  
  475. #define TO_FIND_HDR_PMAGIC  (0)
  476. #define TO_FIND_VERSION_NUM (TO_FIND_HDR_PMAGIC + SIZEOF_PMAGIC + SIZEOF_SPACE)
  477. #define TO_FIND_HTABLE_SIZE (TO_FIND_VERSION_NUM + \
  478.                  SIZEOF_VERSION_NUM + SIZEOF_SPACE)
  479. #define SIZEOF_HDR (TO_FIND_HTABLE_SIZE + \
  480.             SIZEOF_HASH_SIZE + SIZEOF_NEWLINE)
  481.  
  482. #define TO_FIND_SORT_RULE (-(SIZEOF_SORT_RULE + SIZEOF_NEWLINE))
  483. #define TO_FIND_TIMESTAMP (TO_FIND_SORT_RULE + \
  484.                         (-(SIZEOF_TIMESTAMP + SIZEOF_SPACE)))
  485. #define TO_FIND_WIDTHS (TO_FIND_TIMESTAMP + \
  486.             (-(7 * (SIZEOF_SPACE + SIZEOF_WIDTH) + SIZEOF_NEWLINE)))
  487. #define TO_FIND_DELETED_CNT (TO_FIND_WIDTHS + \
  488.             (-(SIZEOF_DELETED_CNT + SIZEOF_NEWLINE)))
  489. #define TO_FIND_COUNT (TO_FIND_DELETED_CNT + \
  490.             (-(SIZEOF_COUNT + SIZEOF_NEWLINE)))
  491. #define TO_FIND_TRLR_PMAGIC (TO_FIND_COUNT + \
  492.             (-(SIZEOF_PMAGIC + SIZEOF_SPACE)))
  493. #define SIZEOF_TRLR (-(TO_FIND_TRLR_PMAGIC))
  494.  
  495. #define SIZEOF_ENTRYREF_ENTRY (SIZEOF_HASH_INDEX + SIZEOF_SPACE + \
  496.                    SIZEOF_HASH_INDEX + SIZEOF_SPACE + \
  497.                    SIZEOF_UID        + SIZEOF_SPACE + \
  498.                    SIZEOF_UID        + SIZEOF_SPACE + \
  499.                    SIZEOF_FILEOFFSET + SIZEOF_NEWLINE)
  500. #define SIZEOF_HTABLE_ENTRY (SIZEOF_HASH_INDEX + SIZEOF_NEWLINE)
  501.  
  502.  
  503. /*
  504.  * Prototypes
  505.  */
  506. int             adrbk_add PROTO((AdrBk *, a_c_arg_t, char *, char *, char *, \
  507.                  char *, char *, Tag, adrbk_cntr_t *, int *));
  508. void            adrbk_clearrefs PROTO((AdrBk *));
  509. void            adrbk_close PROTO((AdrBk *));
  510. void            adrbk_partial_close PROTO((AdrBk *));
  511. adrbk_cntr_t    adrbk_count PROTO((AdrBk *));
  512. int             adrbk_delete PROTO((AdrBk *, a_c_arg_t, int));
  513. char           *adrbk_formatname PROTO((char *));
  514. AdrBk_Entry    *adrbk_get_ae PROTO((AdrBk *, a_c_arg_t, Handling));
  515. int             adrbk_is_in_sort_order PROTO((AdrBk *, int));
  516. int             adrbk_listadd PROTO((AdrBk *, a_c_arg_t, char *));
  517. int             adrbk_nlistadd PROTO((AdrBk *, a_c_arg_t, char **));
  518. int             adrbk_listdel PROTO((AdrBk *, a_c_arg_t, char *));
  519. int             adrbk_listdel_all PROTO((AdrBk *, a_c_arg_t));
  520. AdrBk_Entry    *adrbk_lookup_by_addr PROTO((AdrBk *, char *, adrbk_cntr_t *));
  521. AdrBk_Entry    *adrbk_lookup_by_nick PROTO((AdrBk *, char *, adrbk_cntr_t *));
  522. AdrBk_Entry    *adrbk_newentry PROTO((void));
  523. AdrBk          *adrbk_open PROTO((char *, char *, char *, int, int, int));
  524. long            adrbk_get_nominal_cachesize PROTO((AdrBk *));
  525. long            adrbk_set_nominal_cachesize PROTO((AdrBk *, long));
  526. int             adrbk_sort PROTO((AdrBk *, a_c_arg_t, adrbk_cntr_t *, int));
  527. void            exp_free PROTO((EXPANDED_S *));
  528. adrbk_cntr_t    exp_get_next PROTO ((EXPANDED_S **));
  529. int             exp_is_expanded PROTO((EXPANDED_S *, a_c_arg_t));
  530. void            exp_set_expanded PROTO((EXPANDED_S *, a_c_arg_t));
  531. void            exp_unset_expanded PROTO((EXPANDED_S *, a_c_arg_t));
  532. void            free_ae PROTO((AdrBk *, AdrBk_Entry **));
  533. char          **parse_addrlist PROTO((char *));
  534.  
  535. #endif /* _ADRBKLIB_INCLUDED */
  536.